package org.luxor.commons.storage.client.qiniu;

import com.qiniu.common.QiniuException;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.luxor.commons.core.utils.StrKit;
import org.luxor.commons.storage.client.AbstractStorageClient;
import org.luxor.commons.storage.client.AbstractStorageProperties;
import org.luxor.commons.storage.constant.StorageType;
import org.luxor.commons.storage.exception.StorageServiceException;
import org.luxor.commons.storage.exception.StorageTypeNotSupportedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 七牛 文件存储服务
 *
 * @author Mr.yan @date 2020/2/8
 */
public class QiniuStorageClient extends AbstractStorageClient {
    private static final Logger logger = LoggerFactory.getLogger(QiniuStorageClient.class);

    /**
     * 七牛 全局配置项
     */
    private QiniuProperties properties;

    private UploadManager uploadManager;
    private BucketManager bucketManager;

    private Auth auth;
    private Client client;

    public QiniuStorageClient(QiniuProperties properties) {
        this.properties = properties;
        if (this.isEnabled()) {
            this.init();
        }
    }

    private void init() {
        logger.info("Initialization Qiniu open ( Running Qiniu Connector)");
        try {
            Configuration cfg = new Configuration(Region.huanan());
            client = new Client(cfg);
            auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
            bucketManager = new BucketManager(auth, cfg);
            uploadManager = new UploadManager(cfg);
            logger.info("Initialize Qiniu Connector Success,bye");
        } catch (Throwable e) {
            logger.error("Initialize Qiniu Connector Failure!", e);
            throw e;
        }
    }

    @Override
    public AbstractStorageProperties getConfig() {
        return this.properties;
    }

    @Override
    public boolean isEnabled() {
        return properties.isEnabled();
    }

    @Override
    public String upload(byte[] fileByte, String fileName, String suffix) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 七牛文件存储功能");
            throw new StorageTypeNotSupportedException("[未开启] 七牛文件存储功能");
        }
        try {
            String fileFullPath = getFilePath(StorageType.QINIU, properties.getPrefix(), fileName, suffix);
            logger.info("上传文件,路径:{}", fileFullPath);

            String uploadToken = auth.uploadToken(properties.getBucketName());
            String key = fileFullPath.startsWith(StrKit.SLASH) ? fileFullPath.substring(1) : fileFullPath;
            Response response = uploadManager.put(fileByte, key, uploadToken);
            if (response.isOK()) {
                return fileFullPath;
            } else {
                logger.error("七牛云服务上传失败! 详情:{}", response);
                return null;
            }
        } catch (QiniuException e) {
            logger.error("上传文件失败，请核对七牛配置信息", e);
            throw new StorageServiceException("上传文件失败，请核对七牛配置信息", e);
        }
    }

    @Override
    public byte[] download(String fileFullPath) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 七牛文件存储功能. fileFullPath:{}", fileFullPath);
            throw new StorageTypeNotSupportedException("[未开启] 七牛文件存储功能");
        }
        logger.info("下载文件,路径:{}", fileFullPath);

        try {
            String publicDownloadUrl = properties.getDomain() + fileFullPath;
            String privateDownloadUrl = auth.privateDownloadUrl(publicDownloadUrl);
            StringMap headers = new StringMap();
            headers.put("Connection", "close");
            Response response = client.get(privateDownloadUrl, headers);
            if (response.isOK()) {
                return response.body();
            } else {
                logger.error("七牛云服务下载失败! 详情:{}", response);
                return new byte[]{};
            }
        } catch (QiniuException e) {
            logger.error("下载文件失败，请核对七牛配置信息", e);
            throw new StorageServiceException("下载文件失败，请核对七牛配置信息", e);
        }
    }

    @Override
    public void delete(String fileFullPath) {
        if (!this.isEnabled()) {
            logger.error("[未开启] 七牛文件存储功能. fileFullPath:{}", fileFullPath);
            throw new StorageTypeNotSupportedException("[未开启] 七牛文件存储功能");
        }
        logger.info("删除文件,路径:{}", fileFullPath);

        try {
            String bucketName = properties.getBucketName();
            String key = fileFullPath.startsWith(StrKit.SLASH) ? fileFullPath.substring(1) : fileFullPath;
            Response response = bucketManager.delete(bucketName, key);
            if (!response.isOK()) {
                logger.warn("七牛云服务删除失败! 详情:{}", response);
            }
        } catch (QiniuException e) {
            logger.error("删除文件失败，请核对七牛配置信息", e);
            throw new StorageServiceException("删除文件失败，请核对七牛配置信息", e);
        }
    }

}
